package cn.nextProject.filter;

import cn.nextProject.Utils.CommonUtils;
import cn.nextProject.Utils.JWTUtils;
import cn.nextProject.entity.Permission;
import cn.nextProject.entity.Result;
import cn.nextProject.entity.User;
import cn.nextProject.service.UserService;
import cn.nextProject.service.impl.UserServiceImpl;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
@WebFilter(urlPatterns = "/*")
public class JWTFilter implements Filter {

    @Autowired
    private UserService userService;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //前置：强制转换为http协议的请求对象、响应对象 （转换原因：要使用子类中特有方法）
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //1.获取请求url
        String url = request.getRequestURL().toString();
        log.info("请求路径：{}", url); //请求路径：http://localhost:8080/login

        String realUrl  = "/" + url.substring(url.lastIndexOf("/") + 1);

        //2.判断请求url中是否包含login，如果包含，说明是登录操作，放行
        if("/login".equals(realUrl) || "/register".contains(realUrl)){
            filterChain.doFilter(request, response);//放行请求
            return;//结束当前方法的执行
        }


        //3.获取请求头中的令牌（token）
        String token = request.getHeader("Authorization");
        log.info("从请求头中获取的令牌：{}",token);


        //4.判断令牌是否存在，如果不存在，返回错误结果（未登录）
        if(!StringUtils.hasLength(token)){
            log.info("Token不存在");

//            Result responseResult = Result.error("NOT_LOGIN");
            //把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)
//            String json = JSONObject.toJSONString(responseResult);
            response.setContentType("application/json;charset=utf-8");
            //响应
            response.getWriter().write("Token不存在！");

            return;
        }

        token = token.replace("Bearer ", "");
        token = token.trim();
        //5.解析token，如果解析失败，返回错误结果（未登录）
        try {
            DecodedJWT verify = JWTUtils.verify(token);
            // 获取 payload 中的 tree 字段
            String usernameFromToken = JWTUtils.getUsernameFromToken(verify);
            if (!ObjectUtils.isEmpty(usernameFromToken)){
                CommonUtils.setUsername(usernameFromToken);
                //查询用户是否存在此权限
                User user = userService.getUserByUsername(usernameFromToken);
                if (user == null){
                    response.setContentType("application/json;charset=utf-8");
                    //响应
                    response.getWriter().write("用户无权限！");

                    return;
                }

                if (CollectionUtils.isEmpty(user.getRoleGroupList())){
                    response.setContentType("application/json;charset=utf-8");
                    //响应
                    response.getWriter().write("用户无权限！");
                    return;
                }
                Map<Integer, String> trueMap = new HashMap<>();
                user.getRoleGroupList().forEach(roleGroup -> {
                    List<Permission> permissionList = roleGroup.getPermissionList();
                    if (!CollectionUtils.isEmpty(permissionList)){
                        permissionList.forEach(permission -> {
                            if (realUrl.equals(permission.getPath())){
                                trueMap.put(1, "放行");
                            }
                        });
                    }
                });

                if (trueMap.isEmpty() || trueMap.get(1) == null){
                    response.setContentType("application/json;charset=utf-8");
                    //响应
                    try {
                        response.getWriter().write("用户无权限！");
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                    return;
                }
            }else {
                response.setContentType("application/json;charset=utf-8");
                //响应
                response.getWriter().write("Token验证未通过！");

                return;
            }
        }catch (Exception e){
            log.info("令牌解析失败!");

//            Result responseResult = Result.error("NOT_LOGIN");
            //把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)
//            String json = JSONObject.toJSONString(responseResult);
            response.setContentType("application/json;charset=utf-8");
            //响应
            response.getWriter().write("Token验证未通过！");

            return;
        }

        //6.放行
        try{
            filterChain.doFilter(request, response);
        }finally {
            //清除用户名
            CommonUtils.clearUsername();
        }
    }

}
